package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.RecommendUser;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.pojo.Visitors;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;

@Service
@Slf4j
public class UserLikeApiImpl implements UserLikeApi {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    public static final String LIKE_REDIS_KEY_PREFIX = "USER_LIKE_";

    public static final String NOT_LIKE_REDIS_KEY_PREFIX = "USER_NOT_LIKE_";

    @Autowired
    private MongoTemplate mongoTemplate;

    //喜欢
    @Override
    public Boolean likeUser(Long userId, Long likeUserId) {
        //判断该用户是否已经喜欢 如果已喜欢就返回
        if (this.isLike(userId, likeUserId)) {
            return false;
        }
        //之前没喜欢 修改为喜欢
        //创建喜欢用户对象
        UserLike userLike = new UserLike();
        userLike.setId(ObjectId.get());
        userLike.setUserId(userId);
        userLike.setCreated(System.currentTimeMillis());
        userLike.setLikeUserId(likeUserId);
        //存入mongoDB中
        mongoTemplate.save(userLike);
        //保存到redis中
        String redisKey = this.getLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        //保存到redis中
        redisTemplate.opsForHash().put(redisKey, hashKey, "1");
        //判断 喜欢的用户是否在不喜欢的列表中 如果在 就需要删除数据
        if (this.isNotLike(userId, likeUserId)) {
            redisKey = this.getNotLikeRedisKey(userId);
            redisTemplate.opsForHash().delete(redisKey, hashKey);
        }
        return true;
    }

    //获取不喜欢rediskey
    private String getNotLikeRedisKey(Long userId) {
        return NOT_LIKE_REDIS_KEY_PREFIX + userId;
    }

    //是否已不喜欢
    private boolean isNotLike(Long userId, Long likeUserId) {
        String redisKey = getNotLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        return redisTemplate.opsForHash().hasKey(redisKey, hashKey);
    }

    //是否已喜欢
    public boolean isLike(Long userId, Long likeUserId) {
        String redisKey = getLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        return redisTemplate.opsForHash().hasKey(redisKey, hashKey);
    }

    //获取rediskey
    private String getLikeRedisKey(Long userId) {
        return LIKE_REDIS_KEY_PREFIX + userId;
    }

    //不喜欢
    @Override
    public Boolean notLikeUser(Long userId, Long likeUserId) {
        //1.判断是否已经不喜欢 如果已经不喜欢 直接返回
        if (this.isNotLike(userId, likeUserId)) {
            return false;
        }
        //2.将用户保存到不喜欢列表中
        String notLikeRedisKey = this.getNotLikeRedisKey(userId);
        String hashKey = String.valueOf(likeUserId);
        redisTemplate.opsForHash().put(notLikeRedisKey, hashKey, "1");
        //3.判断用户是否在喜欢表中 如果则需要删除
        if (this.isLike(userId, likeUserId)) {
            //4.存在 删除mongoDB数据
            Query query = Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId));
            mongoTemplate.remove(query, UserLike.class);
            //5.删除redis数据
            notLikeRedisKey = this.getLikeRedisKey(userId);
            redisTemplate.opsForHash().delete(notLikeRedisKey, hashKey);
        }
        return true;
    }

    //是否相互喜欢
    @Override
    public Boolean isMutualLike(Long userId, Long likeUserId) {
        return this.isLike(userId, likeUserId) && this.isLike(likeUserId, userId);
    }

    //查询喜欢列表
    @Override
    public List<Long> queryLikeList(Long userId) {
        // 查询redis
        String redisKey = this.getLikeRedisKey(userId);
        Set<Object> keys = this.redisTemplate.opsForHash().keys(redisKey);
        if (CollUtil.isEmpty(keys)) {
            return ListUtil.empty();
        }

        List<Long> result = new ArrayList<>(keys.size());
        keys.forEach(o -> result.add(Convert.toLong(o)));
        return result;
    }

    //查询不喜欢列表
    @Override
    public List<Long> queryNotLikeList(Long userId) {
        // 查询redis
        String redisKey = this.getNotLikeRedisKey(userId);
        Set<Object> keys = this.redisTemplate.opsForHash().keys(redisKey);
        if (CollUtil.isEmpty(keys)) {
            return ListUtil.empty();
        }

        List<Long> result = new ArrayList<>(keys.size());
        keys.forEach(o -> result.add(Convert.toLong(o)));
        return result;
    }

    //查询我喜欢的用户数量
    @Override
    public Long queryMyLikeUserCount(Long uid) {
        Query query = Query.query(Criteria.where("userId").is(uid));
        long count = mongoTemplate.count(query, UserLike.class);
        return count;
    }

    //查询喜欢我的用户数量
    @Override
    public Long queryLikeMeUserCount(Long uid) {
        Query query = Query.query(Criteria.where("likeUserId").is(uid));
        long count = mongoTemplate.count(query, UserLike.class);
        return count;
    }

    //查询互相喜欢的用户数量
    @Override
    public Long mutualLikeUserCount(Long uid) {
        Query query = Query.query(Criteria.where("userId").is(uid));
        List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);

        List<UserLike> like = new ArrayList<>();
        for (UserLike userLike : userLikes) {
            Query queryPlus = Query.query(Criteria.where("userId").is(userLike.getLikeUserId()).and("likeUserId").is(userLike.getUserId()));
            UserLike one = mongoTemplate.findOne(queryPlus, UserLike.class);
            if (ObjectUtil.isNotEmpty(one)) {
                like.add(userLike);
            }
        }
        return Convert.toLong(like.size());
    }

    //查询我喜欢的用户
    @Override
    public List<UserLike> queryMyLikeUser(Long uid, Integer page, Integer pageSize) {
        Query query = Query.query(Criteria.where("userId").is(uid));
        List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
        return userLikes;
    }

    //查询喜欢我的用户
    @Override
    public List<UserLike> queryLikeMeUser(Long uid, Integer page, Integer pageSize) {
        Query query = Query.query(Criteria.where("likeUserId").is(uid));
        List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
        return userLikes;
    }

    //查询互相喜欢的用户
    @Override
    public List<UserLike> mutualLikeUser(Long uid, Integer page, Integer pageSize) {
        //查询我喜欢的用户
        Query query = Query.query(Criteria.where("userId").is(uid));
        List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
        List<UserLike> mutualLikeUser = new ArrayList<>();
        for (UserLike userLike : userLikes) {
            Query queryPlus = Query.query(Criteria.where("userId").is(userLike.getLikeUserId()).and("likeUserId").is(userLike.getUserId()));
            UserLike one = mongoTemplate.findOne(queryPlus, UserLike.class);
            if (ObjectUtil.isNotEmpty(one)) {
                mutualLikeUser.add(userLike);
            }
        }
        /*//hutool分页工具
        int[] startEnd = PageUtil.transToStartEnd(page - 1, pageSize);
        int startIndex = startEnd[0]; //开始 0 10 20
        int endIndex = Math.min(startEnd[1], mutualLikeUser.size()); //结束 10 20 20
        List<UserLike> vids = new ArrayList<>();
        for (int i = startIndex; i < endIndex; i++) {
            vids.add(mutualLikeUser.get(i));
        }*/
        return mutualLikeUser;
    }

    //谁看过我列表
    @Override
    public List<Visitors> queryLookMeUser(Long uid, Integer page, Integer pageSize) {
        PageRequest pageRequest = PageRequest.of(page-1, pageSize, Sort.by(Sort.Order.desc("date")));
        Query query = Query.query(Criteria.where("userId").is(uid)).with(pageRequest);
        List<Visitors> visitors = mongoTemplate.find(query, Visitors.class);

        for (Visitors visitor : visitors) {
            //查询缘分值
            Query queryScore = Query.query(Criteria.where("toUserId").is(uid).and("userId").is(visitor.getVisitorUserId()));
            RecommendUser recommendUser = mongoTemplate.findOne(queryScore, RecommendUser.class);
            if (ObjectUtil.isEmpty(recommendUser)) {
                visitor.setScore(90D);
            } else {
                visitor.setScore(recommendUser.getScore());
            }
        }
        return visitors;
    }

    //喜欢 - 取消
    @Override
    public void dislike(Long userId, String likeUserId) {
        //查询条件
        Query query = new Query(Criteria.where("likeUserId").is(Long.valueOf(likeUserId)).and("userId").is(userId));
        //根据查询条件删除
        mongoTemplate.remove(query,UserLike.class);
    }

    //粉丝 - 喜欢
    @Override
    public void fansLove(Long userId, String likeUserId) {
        //新建UserLike对象
        UserLike userLike = new UserLike();
        userLike.setId(ObjectId.get());
        userLike.setUserId(userId);
        userLike.setLikeUserId(Long.valueOf(likeUserId));
        userLike.setCreated(System.currentTimeMillis());
        //执行保存
        mongoTemplate.save(userLike);
    }

    //是否已喜欢
    @Override
    public Boolean isAlreadyLike(String id, Long userId) {
        //标记位
        Boolean result = false;
        //查询条件
        Query query = new Query(Criteria.where("userId").is(userId).and("likeUserId").is(Long.valueOf(id)));
        //查询
        UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
        //判断是否已喜欢
        if(ObjectUtil.isNotEmpty(userLike)){
            //如果不为空 代表已经喜欢 修改标记位为真
            result = true;
        }
        return result;
    }

}
